import 'dart:async';

import 'package:flutter/material.dart';
import 'package:gold/app/app.dart';
import 'package:gold/app/user_provider.dart';
import 'package:gold/base/view_model.dart';
import 'package:gold/http/api_login.dart';
import 'package:gold/http/entity_utils.dart';
import 'package:gold/http/http.dart';
import 'package:gold/route/xfg_nav.dart';
import 'package:gold/utils/cache_data.dart';
import 'package:gold/utils/xfg_extension.dart';
import 'package:gold/utils/xfg_utils.dart';

/// @description:
/// @author tangzhentao
/// @created at 19:32 2024/11/24

class LoginViewModel extends Viewmodel {
  /// 手机号
  final TextEditingController phoneController = TextEditingController();
  final FocusNode phoneNode = FocusNode();

  /// 密码或验证码
  final TextEditingController codeController = TextEditingController();
  final FocusNode codeNode = FocusNode();

  /// 验证码计时器
  Timer? _timer;
  /// 验证码倒计时
  int _codeSecond = 60;
  int get codeSecond => _codeSecond;
  set codeSecond(int value) {
    if (_codeSecond != value) {
      _codeSecond = value;
      notifyListeners();
    }
  }

  /// 验证码登录
  bool _isCodeLogin = true;
  bool get isCodeLogin => _isCodeLogin;

  /// 是否可点击
  bool _canClick = false;
  bool get canClick => _canClick;

  /// 发送验证码是否可以点击
  bool _canCodeClick = false;
  bool get canCodeClick => _canCodeClick;
  set canCodeClick(bool value) {
    if (_canCodeClick != value) {
      _canCodeClick = value;
      notifyListeners();
    }
  }

  /// 是否同意协议
  bool _isAgree = false;
  bool get isAgree => _isAgree;

  LoginViewModel() {
    CacheData().getBool(App.agree).then((result) {
      _isAgree = result?? false;
      notifyListeners();
    });
  }

  /// 手机号变化
  void phoneChanged(String phone) {
    bool changed = false;
    final codeClick = isPhone(phone);
    if (isCodeLogin && _canCodeClick != codeClick) { _canCodeClick = codeClick; changed = true; }
    final click = codeClick && codeController.text.isNotEmpty && _isAgree;
    if (_canClick != click) { _canClick = click; changed = true; }
    if (changed) notifyListeners();
  }

  /// 验证码或密码变化
  void codeChanged(String psd) {
    final click = isPhone(phoneController.text) && psd.isNotEmpty && _isAgree;
    if (_canClick != click) {
      _canClick = click;
      notifyListeners();
    }
  }

  /// 发送验证码
  Future sendCode() async {
    hideKeyboard();
    if (_codeSecond != 60) return;
    final result = await Http().request<String>(ApiLogin.sendSmsCode,
        data: {'mobile': phoneController.text, 'event': 'login'}, successText: '已发送');
    if (result.success) {
      _startTimer();
    }
  }

  /// 改变同意协议的状态
  Future changeAgree() async {
    _isAgree = !_isAgree;
    await CacheData().setBool(App.agree, _isAgree);
    final canClick = isPhone(phoneController.text) && codeController.text.isNotEmpty && _isAgree;
    _canClick = canClick;
    notifyListeners();
  }

  /// 切换手机号/验证码登录
  Future changeCodeOrPassword() async {
    hideKeyboard();
    _isCodeLogin = !_isCodeLogin;
    phoneController.text = '';
    codeController.text = '';
    _canClick = false;
    _canCodeClick = false;
    _cancelTimer();
    notifyListeners();
  }

  /// 登录
  Future login() async {
    hideKeyboard();
    final Entity<String> result;
    if (_isCodeLogin) {
      result = await Http().request<String>(ApiLogin.loginByCaptcha,
          data: {'mobile': phoneController.text, 'captcha': codeController.text}, loadingText: '登录中...');
    } else {
      result = await Http().request<String>(ApiLogin.loginByPassword,
          data: {'mobile': phoneController.text, 'password': codeController.text}, loadingText: '登录中...');
    }
    if (result.success) {
      if (result.data?.isNotEmpty == true) {
        XfgNav.read<UserProvider>().loginSuccessUpdate(result.data!);
      } else {
        '未获取到登录凭证，请稍后重试'.toast();
      }
    }
  }

  /// 开启计时器
  void _startTimer() {
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      codeSecond--;
      if (codeSecond == 0) {
        _cancelTimer();
      }
    });
  }

  /// 停止计时器
  void _cancelTimer() {
    codeSecond = 60;
    _timer?.cancel();
    _timer = null;
  }

  @override
  void dispose() {
    _cancelTimer();
    hideKeyboard();
    phoneController.dispose();
    codeController.dispose();
    super.dispose();
  }
}